#include "ina226.h"
#include "myiic.h"
#include "bsp.h"

#define CFG_REG 0x00         //
#define SV_REG 0x01          //分流电压， 此处分流电阻为 0.1欧
#define BV_REG 0x02          //总线电压
#define PWR_REG 0x03         //电源功率
#define CUR_REG 0x04         //电流
#define CAL_REG 0x05         //校准，设定满量程范围以及电流和功率测数的
#define ONFF_REG 0x06        //屏蔽 使能 警报配置和转换准备就绪
#define AL_REG 0x07          //包含与所选警报功能相比较的限定值
#define INA226_GET_ADDR 0XFF //包含唯一的芯片标识号
//#define INA226_ADDR1 0x80
//转换次数求平均
#define INA226_AVG_1 0X4000 // default
#define INA226_AVG_4 0X4200
#define INA226_AVG_16 0X4400
#define INA226_AVG_64 0X4600
#define INA226_AVG_128 0X4800
#define INA226_AVG_256 0X4A00
#define INA226_AVG_512 0X4C00
#define INA226_AVG_1024 0X4E00
// VBus转换时间设置 Bus Voltage Conversion Time  us
#define INA226_BVCT_140 0X4000
#define INA226_BVCT_204 0X4040
#define INA226_BVCT_332 0x4080
#define INA226_BVCT_588 0x40C0
#define INA226_BVCT_1100 0x4100 // default
#define INA226_BVCT_2116 0x4140
#define INA226_BVCT_4156 0x4180
#define INA226_BVCT_8244 0x41C0

// Shunt Voltage Conversion Time us
#define INA226_SVCT_140 0X4000
#define INA226_SVCT_204 0X4008
#define INA226_SVCT_332 0x4010
#define INA226_SVCT_588 0x4018
#define INA226_SVCT_1100 0x4020 // default
#define INA226_SVCT_2116 0x4028
#define INA226_SVCT_4156 0x4030
#define INA226_SVCT_8244 0x4038
// Operating Mode
#define INA226_MODE_POWER_DOWN 0x4000 // Power-Down (or Shutdown)
#define INA226_MODE_SV_TRIGGER 0x4001
#define INA226_MODE_BV_TRIGGER 0x4002
#define INA226_MODE_SAB_TRIGGER 0x4003 // Shunt and Bus, Triggered
//#define INA226_MODE_POWER_DOWN 0x4004  // Power-Down (or Shutdown)
#define INA226_MODE_SV_CONTINUE 0x4005
#define INA226_MODE_BV_CONTINUE 0x4006
#define INA226_MODE_SAB_CONTINUE 0x4007 // Shunt and Bus, Continuous  //default

//分流电阻
#define R_SHUNT 0.1f
//分辨率设置
#define INA_BusVoltage_LSB 1.25f           //总线电压分辨率 1.25mV/bit
#define INA_ShuntVoltage_LSB 2.5f          //分流电阻电压分辨率 2.5uV/bit
#define INA_CURRENT_LSB 0.2f              //分辨率 0.2mA/bit 最大量程 0.2mA*32768=6.5536A
#define INA_POWER_LSB 25 * INA_CURRENT_LSB //功率分辨率
//指定电流分辨率与量程
// cal = (uint16_t)(5.12f / (INA_CURRENT_LSB * R_SHUNT));
#define INA_CAL 256

INA226_Data INA226_data;

void INA226_SendData(uint8_t addr, uint8_t reg, uint16_t data)
{
    uint8_t temp = 0;
    while (i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    i2c_start_on_bus(I2C1);
    while(! i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    i2c_master_addressing(I2C1, addr, I2C_TRANSMITTER);
    while(! i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    while((! i2c_flag_get(I2C1, I2C_FLAG_TBE)));
    i2c_data_transmit(I2C1, reg);
    while((!i2c_flag_get(I2C1, I2C_FLAG_BTC)));
    temp = (uint8_t)(data >> 8);//发送高八位
    i2c_data_transmit(I2C1, temp);
    while((!i2c_flag_get(I2C1, I2C_FLAG_BTC)));
    temp = (uint8_t)(data & 0x00ff);//发送低八位
    i2c_data_transmit(I2C1, temp);
    while((!i2c_flag_get(I2C1, I2C_FLAG_BTC)));
    i2c_stop_on_bus(I2C1);
}

uint16_t INA226_ReadData(uint8_t addr, uint8_t reg)
{
    uint16_t temp=0;
    while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
    i2c_start_on_bus(I2C1);//开启总线
    while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
    i2c_master_addressing(I2C1, addr, I2C_TRANSMITTER);//发送地址
    while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);
    while (!i2c_flag_get(I2C1, I2C_FLAG_TBE));
    i2c_data_transmit(I2C1, reg); /* IIC发送数据，AT24C02需要读出数据的地址*/
    while (!i2c_flag_get(I2C1, I2C_FLAG_TBE));/* 等待IIC发送区为空,即发送完成 */
    i2c_start_on_bus(I2C1); /* 再次发送一个起始位到I2C总线 */
    while (!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));                                                         /* 等待起始位发送完成 */
    i2c_master_addressing(I2C1, addr+1, I2C_RECEIVER); /* 发送器件地址,读数据 */
    while (!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));                                   /* 等待从机地址发送完成 */
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND); /* 清除从机地址发送完成标志位 */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);//第一个字节发送ack
    while (!i2c_flag_get(I2C1, I2C_FLAG_RBNE));       /* 等待数据寄存器可读 */
    temp = i2c_data_receive(I2C1);
    temp = temp << 8;
    i2c_ack_config(I2C1, I2C_ACK_DISABLE);         //第二个字节发送nack
    while (!i2c_flag_get(I2C1, I2C_FLAG_RBNE));                                                                                                                                                  /* 等待数据寄存器可读 */
    temp |= i2c_data_receive(I2C1);
    i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND); /* 清除从机地址发送完成标志位 */
    i2c_stop_on_bus(I2C1);
    return temp;
}
uint16_t INA226_Get_ID(uint8_t addr)
{
    uint16_t temp;
    temp = INA226_ReadData(addr, INA226_GET_ADDR);
    return temp;

}


void INA226_Init(void)
{
    I2C1_Init();
    delay_ms(10);
    //初始化控制寄存器，128次转换，每次1.1ms，转换时间1.1ms，开启电压电流测量
    INA226_SendData(INA226_ADDR1, CFG_REG, INA226_AVG_128 | INA226_BVCT_1100 | INA226_SVCT_1100 | INA226_MODE_SAB_CONTINUE);
    
    INA226_SendData(INA226_ADDR1, CAL_REG, INA_CAL);
}

int16_t INA226_Get_ShuntCurrent(uint8_t addr, INA226_Data *INA226_temp)
{
    int16_t temp = 0;
    //INA226_SetRegPointer(addr, CUR_REG);
    temp = INA226_ReadData(addr,CUR_REG);
    INA226_temp->Shunt_Current = temp * INA_CURRENT_LSB;//mA
    return temp;
}

int16_t INA226_Get_ShuntVoltage(uint8_t addr, INA226_Data *INA226_temp)
{
    int16_t temp = 0;
    //INA226_SetRegPointer(addr, SV_REG);
    temp = INA226_ReadData(addr,SV_REG);
    INA226_temp->Shunt_voltage = temp * INA_ShuntVoltage_LSB;//uV
    return temp;
}

int16_t INA226_Get_BusVoltage(uint8_t addr, INA226_Data *INA226_temp)
{
    int16_t temp = 0;
    //INA226_SetRegPointer(addr, BV_REG);
    temp = INA226_ReadData(addr,BV_REG);
    INA226_temp->voltageVal = temp * 1.25f;
    return temp;
}
uint16_t INA226_Get_Power(uint8_t addr, INA226_Data *INA226_temp)
{
    uint16_t temp = 0;
    //INA226_SetRegPointer(addr, PWR_REG);
    temp = INA226_ReadData(addr,PWR_REG);
    INA226_temp->powerVal = temp * INA_POWER_LSB;
    return temp;
}
